//
//  WNTaskVC.swift
//  WalkNovel
//
//  Created by Kevin on 2023/10/11.
//

import UIKit
import FacebookLogin
import KeychainAccess

class WNTaskVC: WNBaseVC {
    
    deinit {
        NotificationCenter.default.removeObserver(self, name: WNNotiName.rechargeNoti, object: nil)
    }
    
    lazy var scroView: UIScrollView = {
        let scro = UIScrollView.init(frame: .zero)
        scro.backgroundColor = .clear
        scro.showsHorizontalScrollIndicator = true
        scro.showsVerticalScrollIndicator = false
        scro.alwaysBounceVertical = true
        return scro
    }()
    
    lazy var dataView: UIView = {
        let view = UIView()
        view.backgroundColor = .init(named: "white_F7F7F7")
        return view
    }()
    
    lazy var goldView: EarnGoldView = {
        let view = EarnGoldView()
        return view
    }()
    
    lazy var dailyView: EarnDailyView = {
        let view = EarnDailyView()
        view.isHidden = true
        view.taskClosure = { [weak self] task in
            self?.taskRequest(task.taskId, task.gold)
        }
        return view
    }()
    
    lazy var userView: EarnUserView = {
        let view = EarnUserView()
        view.isHidden = true
        view.taskClosure = { [weak self] task in
            if task.status == 2 {
                self?.taskRequest(task.taskId, task.gold)
            }else if task.status == 3 {
                self?.wn_pushBookVC(task.bookId ?? "")
            }
        }
        return view
    }()
    
    lazy var activeView: EarnActiveView = {
        let view = EarnActiveView()
        view.isHidden = true
        view.taskClosure = { [weak self] task in
            if task.activityType == 2 {
                let m = RechargeDetailModel(currency: "usd", productName: task.productName, productId: task.productId, goldGive: task.gold, disGold: task.disGold, price: task.price, gold: task.old_gold, productIds: task.productIds)
                showSpringType(.unlockedRecharge, showStr1: "\(task.status)")
                WNSpringView.shared.unlockedModel = m
                WNSpringView.shared.isRightClosure = { isRight in
                    if isRight && task.status == 2 {
                        WNBuriedManager.shared.logProductItem(m.productId ?? "", m.productName ?? "", m.price)
                        WNReadPayManager.shared.creatReadRechargeOrder(task.taskId, m.productId ?? "", m.productName ?? "", m.productIds ?? "", m.price)
                    }
                }
            }else {
                if task.status == 2 {
                    self?.taskRequest(task.taskId, task.gold)
                }else if task.status == 3 {
                    self?.wn_pushBookVC(task.bookId ?? "")
                }
            }
        }
        return view
    }()
    
    
    var taskArr = [TaskModel]()
    
    var dailyTaskArr = [TaskModel]()
    
    var userTaskArr = [TaskModel]()
    
    var activeTaskArr = [TaskModel]()
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        getDataConfig()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewConfig() {
        view.backgroundColor = .init(named: "white_F7F7F7")
        view.addSubview(scroView)
        scroView.addSubview(dataView)
        dataView.addSubview(goldView)
        dataView.addSubview(activeView)
        dataView.addSubview(dailyView)
        dataView.addSubview(userView)
        scroView.snp.makeConstraints { make in
            make.top.equalTo(NaviTotalHeight)
            make.left.bottom.right.equalTo(0)
        }
        dataView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
            make.height.equalTo(144+15+TabBarMargin)
            make.width.equalTo(ScreenW)
        }
        goldView.snp.makeConstraints { make in
            make.top.equalTo(15)
            make.left.equalTo(15)
            make.right.equalTo(-15)
            make.height.equalTo(144)
        }
        activeView.snp.makeConstraints { make in
            make.top.equalTo(goldView.snp.bottom).offset(15)
            make.left.equalTo(15)
            make.right.equalTo(-15)
            make.height.equalTo(0)
        }
        dailyView.snp.makeConstraints { make in
            make.top.equalTo(activeView.snp.bottom).offset(15)
            make.left.equalTo(15)
            make.right.equalTo(-15)
            make.height.equalTo(0)
        }
        userView.snp.makeConstraints { make in
            make.top.equalTo(dailyView.snp.bottom).offset(15)
            make.left.equalTo(15)
            make.right.equalTo(-15)
            make.height.equalTo(0)
        }
    }
    
    override func dataConfig() {
        pageName = "Task"
        navView.titleName = "Task"
    }
    
    override func handleNoti() {
        NotificationCenter.default.addObserver(forName: WNNotiName.rechargeNoti, object: nil, queue: nil) { [weak self] not in
            self?.getDataConfig()
        }
    }
}

extension WNTaskVC {
    
    func getDataConfig() {
        let group = DispatchGroup()
        group.enter()
        provider_user.rx.request(.userBalance)
            .asObservable()
            .mapModel(BaseModel<BalanceModel>.self)
            .subscribe(onNext: { (model) in
                guard model.code == 0 else { return group.leave() }
                if let balance = model.data?.gold {
                    WNSingleData.shared.userGold = balance
                }
                group.leave()
            }, onError: { (error) in
                group.leave()
            }).disposed(by: rx.disposeBag)
        group.enter()
        provider_task.rx.request(.getTask)
            .asObservable().mapModel(BaseModel<[TaskModel]>.self)
            .subscribe(onNext: { [weak self] (model) in
                guard model.code == 0 else { return group.leave() }
                if let arr = model.data {
                    self?.taskArr = arr
                }
                group.leave()
            }, onError: { [weak self] (error) in
                group.leave()
                self?.wn_toast("Check the network connection")
            }).disposed(by: rx.disposeBag)
        group.notify(queue: DispatchQueue.main) { [weak self] in
            self?.hanleData()
        }
    }
    
    func taskRequest(_ taskId: Int, _ gold: Int) {
        provider_task.rx.request(.completeTask(taskId))
            .asObservable().mapModel(BaseModel<Any>.self)
            .subscribe(onNext: { [weak self] (model) in
                guard model.code == 0 else {
                    self?.wn_toast(model.msg ?? "")
                    return
                }
                self?.wn_toast(gold > 0 ? "Get \(gold) Golds" : (model.msg ?? ""))
                self?.getDataConfig()
            }, onError: { [weak self] (error) in
                self?.wn_toast("Check the network connection")
            }).disposed(by: rx.disposeBag)
    }
    
    func loginByFacebook(_ token: String, _ userId: String, _ name: String, _ email: String, _ headUrl: String) {
        WNHUD.wn_showLoading()
        provider_login.rx.request(.facebookLogin(token, userId, name, email, headUrl))
            .asObservable().mapModel(BaseModel<UserDetailModel>.self)
            .subscribe(onNext: { [weak self] (model) in
                guard model.code == 0 else {
                    self?.wn_toast(model.msg ?? "")
                    return
                }
                if let m = model.data {
                    WNBuriedManager.shared.signIn("FB", m.userId ?? "")
                    saveUser(user: m)
                    setKeyUserId(m.userId ?? "")
                    WNSingleData.shared.userGold = m.gold
                    self?.wn_toast("Bind successed")
                }else {
                    self?.wn_toast("")
                }
            }, onError: { [weak self] (error) in
                self?.wn_toast("Check the network connection")
            }).disposed(by: rx.disposeBag)
    }
    
    func bindFacebook() {
        LoginManager().logOut()
        LoginManager().logIn(permissions: ["public_profile", "email"], from: self) { [weak self] (signInResult, error) in
            guard error == nil else { return }
            guard let signInResult = signInResult else { return }
            if signInResult.isCancelled {
                self?.wn_toast("You canceled your authorization")
            }else {
                let userID = signInResult.token?.userID ?? ""
                Profile.loadCurrentProfile { profile, error in
                    guard error == nil else { return }
                    guard let profile = profile else { return }
                    let token = signInResult.token?.tokenString ?? ""
                    let userId = profile.userID
                    let email = profile.email ?? ""
                    let name = profile.name ?? ""
                    let avatar = profile.imageURL(forMode: .square, size: .init(width: 200, height: 200))?.absoluteString ?? ""
                    self?.loginByFacebook(token, userId, name, email, avatar)
                }
            }
        }
    }
}

extension WNTaskVC {
    
    func hanleData() {
        dailyTaskArr = taskArr.filter({$0.taskType == 1})
        userTaskArr = taskArr.filter({$0.taskType == 2})
        activeTaskArr = taskArr.filter({$0.taskType == 3})
        let w = wn_getTextW(textStr: "\(WNSingleData.shared.userGold)", font: .wn_font(name: .bold, size: 40), height: 40)*0.5
        goldView.headerImage.snp.updateConstraints { make in
            make.centerX.equalToSuperview().offset(-8-w)
        }
        goldView.goldCount.text = "\(WNSingleData.shared.userGold)"
        goldView.headerImage.wn_setupImg(getUser()?.avatar, placeHolder: "placeholder_header")
        
        activeView.activeTaskArr = activeTaskArr
        var ah: CGFloat = 0
        switch activeTaskArr.count {
        case 0:
            ah = 0
        case 1:
            ah = 77+54
        default:
            ah = 77+54+170
        }
        activeView.snp.updateConstraints { make in
            make.top.equalTo(goldView.snp.bottom).offset(activeTaskArr.count == 0 ? 0 : 15)
            make.height.equalTo(ah)
        }
        
        dailyView.dailyTaskArr = dailyTaskArr
        var dh: CGFloat = 0
        if dailyTaskArr.count > 0 {
            dh = CGFloat(dailyTaskArr.count*77+54)
        }
        dailyView.snp.updateConstraints { make in
            make.top.equalTo(activeView.snp.bottom).offset(dailyTaskArr.count == 0 ? 0 : 15)
            make.height.equalTo(dh)
        }
        
        if userTaskArr.count > 1 {
            userTaskArr[1].status = 1
            if (userTaskArr[1].children?.filter({$0.status == 2}).count ?? 0) > 0 {
                userTaskArr[1].status = 2
            }
            if (userTaskArr[1].children?.filter({$0.status == 3}).count ?? 0) == (userTaskArr[1].children?.count ?? 0) {
                userTaskArr[1].status = 3
            }
        }
        userView.userTaskArr = userTaskArr
        var uh: CGFloat = 0
        switch userTaskArr.count {
        case 0:
            uh = 0
        case 1:
            uh = 42+77+12
        case 2:
            uh = 42+77+174+12
        default:
            uh = 42+77+135+174+12
        }
        userView.snp.updateConstraints { make in
            make.height.equalTo(uh)
        }
        
        let ch: CGFloat = 144+(dh > 0 ? dh+15 : 0)+(uh > 0 ? uh+15 : 0)+(ah > 0 ? ah+15 : 0)+15+TabBarMargin
        dataView.snp.updateConstraints { make in
            make.height.equalTo(ch)
        }
        scroView.contentSize = .init(width: ScreenW, height: ch)
        view.layoutIfNeeded()
    }
}
